package com.soc.auth.security;

import com.soc.auth.constants.RedisConstants;
import com.soc.auth.exception.BadCaptchaException;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;

import java.util.Objects;

@Component
@RequiredArgsConstructor
public class    PhoneCaptchaAuthenticationProvider implements AuthenticationProvider {

    private final MyUserDetailServiceImpl myUserDetailService;

    private final RedisTemplate<String, Object> redisTemplate;

    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {

        // 获得手机号和验证码
        String phone = authentication.getName();
        String captcha1 = authentication.getCredentials().toString();

        // 从session中获取验证码
//        ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
//        Assert.notNull(servletRequestAttributes, "获取不到ServletRequestAttributes");
//        HttpServletRequest request = servletRequestAttributes.getRequest();
//        HttpSession session = request.getSession();
//        String captcha2 = (String) session.getAttribute("captcha:" + phone);

        // 从Redis中获取验证码
        String captcha2 = (String) redisTemplate.opsForValue().get(RedisConstants.CAPTCHA_KEY + phone);
        // 判断Redis中保存的验证码与用户输入的验证码是否相等
        if (!Objects.equals(captcha1, captcha2)){
            throw new BadCaptchaException("验证码输入错误");
        }

        // 通过手机号从数据库查询用户
        SecurityUser securityUser = (SecurityUser) myUserDetailService.loadUserByPhone(phone);
        if (Objects.isNull(securityUser)) {
            throw new UsernameNotFoundException("当前用户不存在");
        }

        // 创建认证过的PhoneAuthenticationToken对象
        PhoneCaptchaAuthenticationToken result = new PhoneCaptchaAuthenticationToken(securityUser, null, securityUser.getAuthorities());
        result.setDetails(authentication.getDetails());
        return result;
    }

    @Override
    public boolean supports(Class<?> authentication) {
        return (PhoneCaptchaAuthenticationToken.class
                .isAssignableFrom(authentication));
    }

}
